/* theater.cc

TODO: write a better description

*/
#include "copyright.h"

#include "syscall.h"
#include "theater.h"

#define NUM_ROWS	5
#define ROW_SIZE	5
#define MAX_TC	5
#define MAX_CC	5
#define MAX_TT	3
#define	MAX_GROUPS	60


/* Global Variables */

int numGroups;
int numCustomers; /*counter to number the customers*/


/* Customer Data "Structure"*/
int customerNumber[MAX_GROUPS*5];
int customerGroupNumber[MAX_GROUPS*5];
int customerWantsPopcorn[MAX_GROUPS*5];
int customerWantsSoda[MAX_GROUPS*5];
int customerNeedsBathroom[MAX_GROUPS*5];
int customerIsHeadCustomer[MAX_GROUPS*5];
int customerSeatNumber[MAX_GROUPS*5];
int customerHasPopcorn[MAX_GROUPS*5];
int customerHasSoda[MAX_GROUPS*5];
	
/*Head Customer Information*/
int groupSize[MAX_GROUPS];
int groupPopcornSize[MAX_GROUPS];
int groupSodaSize[MAX_GROUPS];
int groupBathroomSize[MAX_GROUPS];
int groupMoney[MAX_GROUPS];
int groupTickets[MAX_GROUPS];
int headCustomerNumber[MAX_GROUPS]; /*the head customers customer number*/
int customerState[MAX_GROUPS];
int customerStateLock[MAX_GROUPS];

/*HeadCustomer - Regular Customer Interaction*/
int headCustomerLock[MAX_GROUPS];
int headCustomerConditionVariable[MAX_GROUPS];
int regularCustomerConditionVariable[MAX_GROUPS];
	
/* Customer Finding Ticket Line */
int ticketClerkLineLock; /* Lock for choosing a line */
int ticketClerkLineConditionVariable[MAX_TC];
int ticketClerkLineCount[MAX_TC];
int ticketClerkState[MAX_TC]; /* 0 = NOT_BUSY, 1 = BUSY, 2 = ON_BREAK, -1 = NOT_AVAILABLE */

/* Customer - TicketClerk Interaction */
int ticketClerkLock[MAX_TC]; /* Lock for Customer - TicketClerk Interaction */
int ticketClerkConditionVariable[MAX_TC];
int ticketClerkRegister[MAX_TC]; /* registers for the ticket clerks */
int ticketClerkNumToSell[MAX_TC]; /* Number of tickets to sell in one transaction*/

/* Customer Finding Concession Line */
int concessionClerkLineLock; /* Lock for choosing a line */
int concessionClerkLineConditionVariable[MAX_CC];
int concessionClerkLineCount[MAX_CC];
int concessionClerkState[MAX_CC]; /* 0 = NOT_BUSY, 1 = BUSY, 2 = ON_BREAK, -1 = NOT_AVAILABLE */

/* Customer - ConcessionClerk Interaction */
int concessionClerkLock[MAX_CC]; /* Lock for Customer - ConcessionClerk Interaction */
int concessionClerkConditionVariable[MAX_CC];
int concessionClerkRegister[MAX_CC]; /*registers for the Concession clerks*/
int concessionClerkPopcornToSell[MAX_CC]; /*number of popcorn selling*/
int concessionClerkSodaToSell[MAX_CC]; /*number of sodas selling*/ 

/*Customer Finding TicketTaker Line*/
int ticketTakerLineLock; /* Lock for choosing a line */
int ticketTakerLineConditionVariable[MAX_TT];
int ticketTakerLineCount[MAX_TT];
int ticketTakerState[MAX_TT]; /* 0 = NOT_BUSY, 1 = BUSY, 2 = ON_BREAK, -1 = NOT_AVAILABLE */

/*Customer - TicketTaker Interaction*/
int ticketTakerLock[MAX_TT]; /* Lock for Customer - TicketTaker Interaction */
int ticketTakerConditionVariable[MAX_TT];
int ticketTakerCounter[MAX_TT];
int numberAdmitted;

/* Lobby variables */
int lobbyConditionVariable;

/* Total register values */
int ticketMoney = 0;
int concessionMoney = 0;

/* Customer Finding Seat Interaction*/
int room[NUM_ROWS];
int seatsFilled = 0;
int movieRoomLock; /* Lock for the room */
int movieRoomConditionVariable;

/* Technician - Customer Interaction */
int movieDataLock; /* Lock for the movie data */
int technicianDataConditionVariable;

/* Manager - Technician Interaction */
int movieStartTime;
int movieEnded;
int movieLength;

/* Manager - End Simulation Information */
int custCounter;
int counterLock;

/* Manager - Ticket Clerk break scenario */
int ticketClerkBreakLock[MAX_TC];
int ticketClerkBreakConditionVariable[MAX_TC];
int ticketClerkBreak[MAX_TC]; /* 1 = on break; 0 = off break; */

/* Manager - Concession Clerk break scenario */
int concessionClerkBreakLock[MAX_CC];
int concessionClerkBreakConditionVariable[MAX_CC];
int concessionClerkBreak[MAX_CC]; /* 1 = on break; 0 = off break; */

/* Manager - Ticket Taker break scenario */
int ticketTakerBreakLock[MAX_TT];
int ticketTakerBreakConditionVariable[MAX_TT];
int ticketTakerBreak[MAX_TT]; /* 1 = on break; 0 = off break; */

/*Bathroom Variables*/
int bathroomLock[MAX_GROUPS];
int bathroomLobbyConditionVariable[MAX_GROUPS];

/*Index Counters for everyone*/

int regularCustomerIndexLock;
int headCustomerIndexLock;
int ticketClerkIndexLock;
int concessionClerkIndexLock;
int ticketTakerIndexLock;
int technicianIndexLock;

int nextRegularCustomer = 0;
int nextRegularHeadCustomer = 0;
int nextCustomerIndex = 0;
int nextHeadCustomer = 0;
int nextTicketClerk = 0;
int nextConcessionClerk = 0;
int nextTicketTaker = 0;
int nextTechnician = 0;
int numFriendsLeft[MAX_GROUPS];

/*Previously Local Variables*/

/* END VARIABLES */


void regularCustomer(){

	int myIndex;
	int tempRegCustomer;
	int i;
	/*TODO: figure out how to number these...*/
	
	/*Printing("Before Acquiring Regular Customer Lock number: %i\n", ConsoleOutput, regularCustomerIndexLock,0);*/
	AcquireLock(regularCustomerIndexLock);
	
		/*Must Loop through all possible regular customers (those not occupied so far) and make sure that there number wasn't designated to a head customer*/
		/*for(i = nextRegularCustomer; i < numCustomers; i++){*/
		/*for(i = nextCustomerIndex; i < numCustomers; i++){
		
			nextRegularCustomer++;
		
			if(!customerIsHeadCustomer[i]){
				myIndex = customerNumber[i];
				
				break;
			} else {
				nextCustomerIndex++;
			}
	
		}*/
		/*if(nextCustomerIndex == nextHeadCustomer - 5){
			nextCustomerIndex++;
		}
		myIndex = nextCustomerIndex;
		nextCustomerIndex++;*/
	
		for(i = nextRegularCustomer; i < numCustomers; i++){
		
			
				
			if(!customerIsHeadCustomer[i]){
				myIndex = nextRegularCustomer;
				nextRegularCustomer++;
				break;
			}
			
			nextRegularCustomer++;
			
		
		}
	/*Printing("Before Releasing Regular Customer Lock index: %i, Lock: %i\n", ConsoleOutput, myIndex,regularCustomerIndexLock);*/
	/*Printing("****************myIndex = %i; nextCustomerIndex = %i;\n", ConsoleOutput, myIndex, nextRegularCustomer);*/
	ReleaseLock(regularCustomerIndexLock);

	/*BEGIN: RegularCustomer - HeadCustomer Interaction, Deciding on Food*/

	AcquireLock(headCustomerLock[customerGroupNumber[myIndex]]);

	/*STEP 1: RegularCustomer waits for Head customer to broadcast (ask them if they want food)*/
	Printing("Customer %i of group %i is waiting for the group to form.\n",ConsoleOutput, myIndex, customerGroupNumber[myIndex]);
	Printing("Customer %i of group %i is waiting for the HeadCustomer.\n", ConsoleOutput, myIndex, customerGroupNumber[myIndex]);
	Wait(regularCustomerConditionVariable[customerGroupNumber[myIndex]], headCustomerLock[customerGroupNumber[myIndex]]);
	Printing("Customer %i of group %i has been told by the HeadCustomer to proceed.\n", ConsoleOutput, myIndex, customerGroupNumber[myIndex]);
  
	/*STEP 2: The customer is asked by the head, andx the regular customer decides if they want food.*/
	customerWantsPopcorn[myIndex] = (Random()%4 > 0) ? 1 : 0;
	customerWantsSoda[myIndex] = (Random()%4 > 0) ? 1 : 0;
	
	Printing("Customer %i in group %i \0", ConsoleOutput, myIndex, customerGroupNumber[myIndex]);
	Printing("wants %i popcorn and %i soda.\n" , ConsoleOutput, customerWantsPopcorn[myIndex],customerWantsSoda[myIndex]);
	
	Printing("Customer %i in Group %i has \0", ConsoleOutput, headCustomerNumber[customerGroupNumber[myIndex]], customerGroupNumber[myIndex]);
	Printing("%i popcorn and %i soda request from a group member\n", ConsoleOutput, customerWantsPopcorn[myIndex], customerWantsSoda[myIndex]);
	

	Signal(headCustomerConditionVariable[customerGroupNumber[myIndex]], headCustomerLock[customerGroupNumber[myIndex]]);
	Wait(regularCustomerConditionVariable[customerGroupNumber[myIndex]], headCustomerLock[customerGroupNumber[myIndex]]);

	/*END: RegularCustomer - HeadCustomer Interaction, Deciding on Food*/
	
	/*BEGIN: RegularCustomer - HeadCustomer Interaction, Getting line from head customer*/
	
	Printing("Customer %i in group %i is sitting in a theater room seat.\n", ConsoleOutput, myIndex, customerGroupNumber[myIndex]);

	/*printf("(RCust%i, group%i: Im in seat %i.)\n", myIndex, customerGroupNumber[myIndex], customerSeatNumber[myIndex]);*/

	Signal(headCustomerConditionVariable[customerGroupNumber[myIndex]], headCustomerLock[customerGroupNumber[myIndex]]);
	Wait(regularCustomerConditionVariable[customerGroupNumber[myIndex]], headCustomerLock[customerGroupNumber[myIndex]]);

	Printing("Customer %i in group %i is getting out of a theater room seat.\n", ConsoleOutput, myIndex, customerGroupNumber[myIndex]);

	
	/*END: RegularCustomer - HeadCustomer Interaction, Getting line from head customer*/

	/*BEGIN: Bathroom deciding*/
	

	customerNeedsBathroom[myIndex] = (Random()%4 > 0) ? 0 : 1;
	
	if(customerNeedsBathroom[myIndex]){
		Printing("Customer %i in Group %i is going to the bathroom.\n", ConsoleOutput, myIndex, customerGroupNumber[myIndex]);
	}
	
	Signal(headCustomerConditionVariable[customerGroupNumber[myIndex]], headCustomerLock[customerGroupNumber[myIndex]]);
	Wait(regularCustomerConditionVariable[customerGroupNumber[myIndex]], headCustomerLock[customerGroupNumber[myIndex]]);


	if(customerNeedsBathroom[myIndex] == 0){

		AcquireLock(bathroomLock[customerGroupNumber[myIndex]]);

		Signal(headCustomerConditionVariable[customerGroupNumber[myIndex]], headCustomerLock[customerGroupNumber[myIndex]]);

	 /*Wait(regularCustomerConditionVariable[customerGroupNumber[myIndex]], headCustomerLock[customerGroupNumber[myIndex]]);*/

		
		/*ReleaseLock(headCustomerLock[customerGroupNumber[myIndex]]);*/
		/*Wait(bathroomLobbyConditionVariable[customerGroupNumber[myIndex]], bathroomLock[customerGroupNumber[myIndex]]);*/

		
		
		ReleaseLock(bathroomLock[customerGroupNumber[myIndex]]);
		
	}
	else{
		
		
	
		AcquireLock(bathroomLock[customerGroupNumber[myIndex]]);

		groupBathroomSize[customerGroupNumber[myIndex]]--;	
		
		/*printf("(RCust%i: Done going to the bathroom  There are still %i people were waiting for.)\n", myIndex,groupBathroomSize[customerGroupNumber[myIndex]]);*/

		ReleaseLock(bathroomLock[customerGroupNumber[myIndex]]);
		
		if(groupBathroomSize[customerGroupNumber[myIndex]] == 0){
			Broadcast(bathroomLobbyConditionVariable[customerGroupNumber[myIndex]], bathroomLock[customerGroupNumber[myIndex]]);
		}

		Signal(headCustomerConditionVariable[customerGroupNumber[myIndex]], headCustomerLock[customerGroupNumber[myIndex]]);
			
		Printing("Customer %i in Group %i is leaving the bathroom.\n", ConsoleOutput, myIndex, customerGroupNumber[myIndex]);
	
	}
	
	/*Wait(regularCustomerConditionVariable[customerGroupNumber[myIndex]], headCustomerLock[customerGroupNumber[myIndex]]);*/

	Printing("Customer %i in Group %i has left the movie theater.\n", ConsoleOutput, myIndex, customerGroupNumber[myIndex]);
	/*END: Bathroom deciding*/
	
	ReleaseLock(headCustomerLock[customerGroupNumber[myIndex]]);
	
	Exit(0);
}

void headCustomer(){
	
	int myIndex;
	int flag;
	int myTicketClerk;
	int shortestTicketClerkLine;
	int shortestTicketClerkLineLength;
	int shortestConcessionLine;
	int shortestConcessionLineLength;
	int i;
	int myTicketTaker;
	int shortestTicketTakerLine ; 
	int shortestTicketTakerLineLength;
	int foundRow;
	int seatNumber;
	int tempGroupSize;
	int j;
	int k;
	int myConcessionClerk;
	int tempRegCustomer;
				

	/*Printing("Before Acquired HeadCustomer Lock %i\n", ConsoleOutput, headCustomerIndexLock,0);*/
	AcquireLock(headCustomerIndexLock);
		/*myIndex = customerGroupNumber[nextHeadCustomer];*/
		/*myIndex = nextHeadCustomer;
		nextHeadCustomer+=5;
		nextCustomerIndex++;*/
		
		myIndex = nextHeadCustomer;
		nextHeadCustomer++;
		/*nextCustomerIndex++;*/
		/*Printing("****************myIndex = %i; nextHeadCustomer = %i; \0", ConsoleOutput, myIndex, nextHeadCustomer);*/
		Printing("nextCustomerIndex = %i\n", ConsoleOutput, nextRegularCustomer, 0);
	ReleaseLock(headCustomerIndexLock);
	/*Printing("After Released HeadCustomer Lock index: %i, lock: %i\n", ConsoleOutput, myIndex,headCustomerIndexLock);*/

	 flag = 1;
		
	/*printf("HCust%i: I am a head customer with groupsize = %i\n", myIndex, groupSize[myIndex] + 1);*/
	
	/*BEGIN: Customer - TicketClerk Interaction*/
	
	myTicketClerk = -1; /* index = -1 */
	
	while(flag){
		/*printf("HCust%i: while flagging a ticket clerk\n", myIndex);*/
		/*Printing("Customer %i of group %i \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);*/
		/*Printing("trying to acquire lock %i!\n", ConsoleOutput, ticketClerkLineLock, 0);*/
		AcquireLock(ticketClerkLineLock); /* Lock for choosing a line */
		/*Printing("Customer %i acquired lock %i!\n", ConsoleOutput, headCustomerNumber[myIndex], ticketClerkLineLock);*/
		
		/* look for a clerk in the NOT_BUSY state */
		for(i = 0; i < MAX_TC; i++){
			/* need to have a check to see if the clerk "exists" and is NOT_BUSY */
			if(ticketClerkState[i] == 0){
				/* dont have to wait, just go to clerk */
				myTicketClerk = i;
				ticketClerkState[i] = 1;
				
				Printing("Customer %i in Group %i \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
				
				Printing("is walking up to TicketClerk %i to buy %i tickets\n", ConsoleOutput, myTicketClerk, groupSize[myIndex] + 1);
				
				
				flag = 0;
				break;
			}
		}
		
		/* if I dont have a clerk (myTicketClerk = -1), choose shortest line */
		if(myTicketClerk == -1){
			/*printf("HCust%i: Finding the shortest line\n", myIndex);*/
			shortestTicketClerkLine = 0; /* index = 0 */
			shortestTicketClerkLineLength = ticketClerkLineCount[0];
			
			/* need to find a starting line that isnt on break */
			for(i = 0; i < MAX_TC; i++){
				if(ticketClerkState[i] == 1){
					/*printf("HCust%i: attempting to acquire TC%is lock to get shortest line\n", myIndex, i);*/
					/*Printing("Customer %i attempting to acquire lock %i to get shortest line1\n", ConsoleOutput, myIndex, ticketClerkBreakLock[i]);*/
					AcquireLock(ticketClerkBreakLock[i]);
					/*Printing("Customer %i acquired lock %i to get shortest line1\n", ConsoleOutput, myIndex, ticketClerkBreakLock[i]);*/
					if(ticketClerkBreak[i] == 0){
						/*printf("HCust%i: found an off break line at TC%i\n", myIndex, i);*/
						shortestTicketClerkLine = i;
						shortestTicketClerkLineLength = ticketClerkLineCount[i];
					}
					/*Printing("Customer %i attempting to release lock %i to get shortest line1\n", ConsoleOutput, myIndex, ticketClerkBreakLock[i]);*/
					ReleaseLock(ticketClerkBreakLock[i]);
					/*Printing("Customer %i released lock %i to get shortest line1\n", ConsoleOutput, myIndex, ticketClerkBreakLock[i]);*/
				}
			}
			
			for(i = 0; i < MAX_TC; i++){
				if(ticketClerkState[i] == 1){
					/*Printing("Customer %i attempting to acquire lock %i to get shortest line2\n", ConsoleOutput, myIndex, ticketClerkBreakLock[i]);*/
					AcquireLock(ticketClerkBreakLock[i]);
					/*Printing("Customer %i acquired lock %i to get shortest line2\n", ConsoleOutput, myIndex, ticketClerkBreakLock[i]);*/
					if(shortestTicketClerkLineLength >= ticketClerkLineCount[i] && ticketClerkBreak[i] == 0){ /* if theres a shorter line than current line */
						/*printf("HCust%i: found a shorter line at TC%i\n", myIndex, i);*/
						shortestTicketClerkLine = i;
						shortestTicketClerkLineLength = ticketClerkLineCount[i];
					}
					/*Printing("Customer %i attempting to release lock %i to get shortest line2\n", ConsoleOutput, myIndex, ticketClerkBreakLock[i]);*/
					ReleaseLock(ticketClerkBreakLock[i]);
					/*Printing("Customer %i released lock %i to get shortest line2\n", ConsoleOutput, myIndex, ticketClerkBreakLock[i]);*/
				}
			}
			
			/* Steps
			1. I must have the shortest line at this point 
			2. Get in that line 
			3. Sleep and give up the lock, will reacquire the lock when signaled */
			
			/*printf("HCust%i: Getting in a line\n", myIndex);*/
			myTicketClerk = shortestTicketClerkLine;
			Printing("Customer %i in Group %i is getting \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
			Printing("in TicketClerk line %i\n", ConsoleOutput,myTicketClerk, 0);
			ticketClerkLineCount[myTicketClerk]++;
			Wait(ticketClerkLineConditionVariable[myTicketClerk], ticketClerkLineLock);
			
			/*printf("HCust%i: i will now try to take TC%is break lock and i have the ticket clerk line lock\n", myIndex, myTicketClerk);*/
			/*Printing("Customer %i attempting to acquire lock %i to check break\n", ConsoleOutput, myIndex, ticketClerkBreakLock[myTicketClerk]);*/
			AcquireLock(ticketClerkBreakLock[myTicketClerk]);
			/*Printing("Customer %i acquired lock %i to check break\n", ConsoleOutput, myIndex, ticketClerkBreakLock[myTicketClerk]);*/
			/*printf("HCust%i: TC%is break lock acquired\n", myIndex, myTicketClerk);*/
			if(ticketClerkBreak[myTicketClerk] == 1){
				
				Printing("Customer %i in Group %i sees TicketClerk \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
				Printing("%i is on break.\n", ConsoleOutput, myTicketClerk, 0);
				ticketClerkLineCount[myTicketClerk]--;
				
				ReleaseLock(ticketClerkLineLock);
				/*Printing("Customer %i attempting to release lock %i to check break1\n", ConsoleOutput, myIndex, ticketClerkBreakLock[myTicketClerk]);*/
				ReleaseLock(ticketClerkBreakLock[myTicketClerk]);
				/*Printing("Customer %i released lock %i to check break1\n", ConsoleOutput, myIndex, ticketClerkBreakLock[myTicketClerk]);*/
				
				myTicketClerk = -1;
			} else if(ticketClerkBreak[myTicketClerk] == 2){
				/*printf("HCust%i: my TC%i is taking too long, gotta find a new line\n", myIndex, myTicketClerk);*/
				ticketClerkLineCount[myTicketClerk]--;
				
				if(ticketClerkLineCount[myTicketClerk] == 0){
					/*printf("HCust%i: TC%i line count == 0\n", myIndex, myTicketClerk);*/
					ticketClerkBreak[myTicketClerk] = 0;
				}
				
				/*Printing("Customer %i attempting to release lock %i to check break2\n", ConsoleOutput, headCustomerNumber[myIndex], ticketClerkLineLock);*/
				ReleaseLock(ticketClerkLineLock);
				/*Printing("Customer %i attempting to release lock %i to check break2\n", ConsoleOutput, myIndex, ticketClerkBreakLock[myTicketClerk]);*/
				ReleaseLock(ticketClerkBreakLock[myTicketClerk]);
				/*Printing("Customer %i released lock %i to check break2\n", ConsoleOutput, myIndex, ticketClerkBreakLock[myTicketClerk]);*/
				
				myTicketClerk = -1;
			} else {
				/*printf("HCust%i: my TC%i isnt on break and doesnt have a huge line. onward!\n", myIndex, myTicketClerk);*/
				flag = 0;
				/*Printing("Customer %i YO WUDDUP\n", ConsoleOutput, headCustomerNumber[myIndex], 0);*/
				/*Printing("Customer %i attempting to release lock %i to check break3\n", ConsoleOutput, myIndex, ticketClerkBreakLock[myTicketClerk]);*/
				ReleaseLock(ticketClerkBreakLock[myTicketClerk]);
				/*Printing("Customer %i released lock %i to check break3\n", ConsoleOutput, myIndex, ticketClerkBreakLock[myTicketClerk]);*/
			}
		}
	}
	
	flag = 1;
	/*printf("HCust%i: releasing the kraken on TC%i \n", myIndex, myTicketClerk);*/
	ReleaseLock(ticketClerkLineLock);
	/*Printing("Customer %i acquiring lock %i\n", ConsoleOutput, headCustomerNumber[myIndex], ticketClerkLock[myTicketClerk]);*/
	AcquireLock(ticketClerkLock[myTicketClerk]);
	/*Printing("Customer %i acquired lock %i\n", ConsoleOutput, headCustomerNumber[myIndex], ticketClerkLock[myTicketClerk]);*/
	
	/*Printing("Customer %i acquiring lock %i\n", ConsoleOutput, headCustomerNumber[myIndex], ticketClerkBreakLock[myTicketClerk]);*/
	AcquireLock(ticketClerkBreakLock[myTicketClerk]);
	/*Printing("Customer %i acquired lock %i\n", ConsoleOutput, headCustomerNumber[myIndex], ticketClerkBreakLock[myTicketClerk]);*/
	
	/*STEP 1: Customer-TicketClerk, Sets the global variable indicating the number of tickets he wants to buy.*/
	/*printf("HCust%i: Hello, TC%i I need %i tickets\n", myIndex, myTicketClerk, (groupSize[myIndex] + 1));*/
	Printing("Customer %i needs tickets from ticketClerk %i\n", ConsoleOutput, headCustomerNumber[myIndex], myTicketClerk);
	ticketClerkNumToSell[myTicketClerk] = (groupSize[myIndex] + 1);
	
	Signal(ticketClerkConditionVariable[myTicketClerk], ticketClerkLock[myTicketClerk]);
	ReleaseLock(ticketClerkBreakLock[myTicketClerk]);
	Wait(ticketClerkConditionVariable[myTicketClerk], ticketClerkLock[myTicketClerk]);
	AcquireLock(ticketClerkBreakLock[myTicketClerk]);

	/*STEP 2: Customer-TicketClerk, Customer hands out the cash.*/
	Printing("Customer %i in Group %i in TicketClerk line \0", ConsoleOutput,headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
	Printing("%i is paying %i for tickets\n", ConsoleOutput, myTicketClerk, (groupSize[myIndex] + 1)*12);
	
	Signal(ticketClerkConditionVariable[myTicketClerk], ticketClerkLock[myTicketClerk]);
	ReleaseLock(ticketClerkBreakLock[myTicketClerk]);
	Wait(ticketClerkConditionVariable[myTicketClerk], ticketClerkLock[myTicketClerk]);
	AcquireLock(ticketClerkBreakLock[myTicketClerk]);
	
	/*STEP 3: Customer-TicketClerk, After the ticket clerks sells the tickets, he takes the tickts (sets groupTickets)*/
	
	Printing("Customer %i is paying %i for tickets\n", ConsoleOutput, headCustomerNumber[myIndex], (groupSize[myIndex] + 1)*12);
	groupTickets[myIndex] = groupSize[myIndex] + 1;

	Signal(ticketClerkConditionVariable[myTicketClerk], ticketClerkLock[myTicketClerk]);
	
	Printing("Customer %i in Group %i is \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
	Printing("leaving TicketClerk %i\n", ConsoleOutput, myTicketClerk, 0);
	ReleaseLock(ticketClerkBreakLock[myTicketClerk]);
	ReleaseLock(ticketClerkLock[myTicketClerk]);
	
	/*printf("HCust%i: I have $%i left in my wallet.\n", myIndex, groupMoney[myIndex]);*/
	
	/*END: Customer - TicketClerk Interaction*/
	
	/*BEGIN: HeadCustomer - RegularCustomer Interaction for Concessions*/
	 

	/*STEP 1: HeadCustomer - RegularCustomer, Tells all of his friends that hes going to order food for them*/
	
	/*Only if the head customer has group members should be acquire the lock, otherwise skip to deciding only for himself*/
	
	if(groupSize[myIndex] > 0){
	
		AcquireLock(headCustomerLock[myIndex]);
						
		/*Asking each one at a time if they want food, then waiting for the next.*/
		Printing("HeadCustomer %i of Group %i has told the group to proceed.\n", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
		for(i = 0; i < groupSize[myIndex]; i++){
			Signal(regularCustomerConditionVariable[myIndex], headCustomerLock[myIndex]);
			Wait(headCustomerConditionVariable[myIndex], headCustomerLock[myIndex]);
		}		
			
		/*STEP 2: The headcustomer decides about food himself, and then tallies the total*/
		customerWantsPopcorn[headCustomerNumber[myIndex]] = (Random()%4 > 0) ? 1 : 0;
		customerWantsSoda[headCustomerNumber[myIndex]] = (Random()%4 > 0) ? 1 : 0;
		
		Printing("Customer %i in Group %i wants \0",ConsoleOutput, customerWantsPopcorn[myIndex], customerWantsSoda[myIndex]);
		Printing("%i popcorn and %i soda.\n", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
		
				
		groupPopcornSize[myIndex] = 0;
		
		/*TODO: You can't find the regular customers this way anymore*/
		for(i = 0; i < numCustomers; i++){
			if(myIndex == customerGroupNumber[i]){
				if(customerWantsPopcorn[i]){
					groupPopcornSize[myIndex]++;
				}
			}
		}
		
		groupSodaSize[myIndex] = 0;
		
		for(i = 0; i < numCustomers; i++){
			if(myIndex == customerGroupNumber[i]){
				if(customerWantsSoda[i]){
					groupSodaSize[myIndex]++;
				}
			}
		}
		
		ReleaseLock(headCustomerLock[myIndex]);
	}
	else{
		/*COPIED from STEP 2: The headcustomer decides about food himself only*/
		customerWantsPopcorn[headCustomerNumber[myIndex]] = (Random()%4 > 0) ? 1 : 0;
		customerWantsSoda[headCustomerNumber[myIndex]] = (Random()%4 > 0) ? 1 : 0;
		groupPopcornSize[myIndex] = customerWantsPopcorn[headCustomerNumber[myIndex]];
		groupSodaSize[myIndex] = customerWantsSoda[headCustomerNumber[myIndex]];
		
		Printing("Customer %i in Group %i wants \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
		Printing("%i popcorn and %i soda.\n",  ConsoleOutput, customerWantsPopcorn[myIndex], customerWantsSoda[myIndex]);
		
	}	
	
	
	/*END: HeadCustomer - RegularCustomer Interaction for Concessions*/
	
	/*BEGIN: Customer - ConcessionClerk Interaction*/
	
	if(groupPopcornSize[myIndex] > 0 || groupSodaSize[myIndex] > 0){
	
		myConcessionClerk = -1; /* index = -1 */
		
		while(flag){
			/*printf("HCust%i: while flagging a concession clerk\n", myIndex);*/
			AcquireLock(concessionClerkLineLock); /* Lock for choosing a line */
			/* look for a clerk in the NOT_BUSY state */
			for(i = 0; i < MAX_CC; i++){
				/* need to have a check to see if the clerk "exists" and is NOT_BUSY */
				if(concessionClerkState[i] == 0){
					/* dont have to wait, just go to clerk */
					myConcessionClerk = i;
					concessionClerkState[i] = 1;
					Printing("Customer %i in Group %i is walking up to \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
					Printing("ConcessionClerk%i to buy %i \0", ConsoleOutput, myConcessionClerk, groupPopcornSize[myIndex]);
					Printing("popcorn and %i soda.\n", ConsoleOutput, groupSodaSize[myIndex], 0);
					flag = 0;
					break;
				}
			}
			
			/* if I dont have a clerk (myConcessionClerk = -1), choose shortest line */
			if(myConcessionClerk == -1){
				/*printf("HCust%i: Finding the shortest food line\n", myIndex);*/
				shortestConcessionLine = 0; /* index = 0 */
				shortestConcessionLineLength = concessionClerkLineCount[0];
				
				for(i = 0; i < MAX_CC; i++){
					if(concessionClerkState[i] == 1){
						AcquireLock(concessionClerkBreakLock[i]);
						if(concessionClerkBreak[i] == 0){
							shortestConcessionLine = i;
							shortestConcessionLineLength = concessionClerkLineCount[i];
						}
						ReleaseLock(concessionClerkBreakLock[i]);
					}
				}
				
				for(i = 1; i < MAX_CC; i++){
					if(concessionClerkState[i] == 1){
						AcquireLock(concessionClerkBreakLock[i]);
						if(shortestConcessionLineLength >= concessionClerkLineCount[i] && concessionClerkBreak[i] == 0){ /* if theres a shorter line than current line and avaliable*/	
							shortestConcessionLine = i;
							shortestConcessionLineLength = concessionClerkLineCount[i];
						}
						ReleaseLock(concessionClerkBreakLock[i]);
					}
				}
				
				/* Steps
				1. I must have the shortest line at this point 
				2. Get in that line 
				3. Sleep and give up the lock, will reacquire the lock when signaled */
				
				/*printf("HCust%i: Getting in a concession line\n", myIndex);*/
				myConcessionClerk = shortestConcessionLine;
				Printing("Customer %i in Group %i is getting \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
				Printing("in ConcessionClerk line %i\n", ConsoleOutput, myConcessionClerk, 0);
				concessionClerkLineCount[myConcessionClerk]++;
				Wait(concessionClerkLineConditionVariable[myConcessionClerk], concessionClerkLineLock);
				
				AcquireLock(concessionClerkBreakLock[myConcessionClerk]);
				if(concessionClerkBreak[myConcessionClerk] == 1){
					concessionClerkLineCount[myConcessionClerk]--;
					
					Printing("Customer %i in Group %i sees ConcessionClerk \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
					Printing("%i is on break.\n",ConsoleOutput, myConcessionClerk, 0);
					ReleaseLock(concessionClerkLineLock);
					ReleaseLock(concessionClerkBreakLock[myConcessionClerk]);
					
					myConcessionClerk = -1;
				} else if(concessionClerkBreak[myConcessionClerk] == 2){
					concessionClerkLineCount[myConcessionClerk]--;
					
					if(concessionClerkLineCount[myConcessionClerk] == 0){
					
						concessionClerkBreak[myConcessionClerk] = 0;
					
					}
					
					ReleaseLock(concessionClerkLineLock);
					ReleaseLock(concessionClerkBreakLock[myConcessionClerk]);
					
					myConcessionClerk = -1;
				} else {
					flag = 0;
					ReleaseLock(concessionClerkBreakLock[myConcessionClerk]);
				}
			}
		}
		
		flag = 1;
		ReleaseLock(concessionClerkLineLock);
		AcquireLock(concessionClerkLock[myConcessionClerk]);
		AcquireLock(concessionClerkBreakLock[myConcessionClerk]);
		
		/*STEP 1: Customer-ConcessionClerk, Tells Concession clerk heres there and read to order.*/
		/*printf("HCust%i: Hello CC%i, I need %i popcorns and %i sodas!\n", myIndex, myConcessionClerk, groupPopcornSize[myIndex], groupSodaSize[myIndex]);*/
		
		concessionClerkPopcornToSell[myConcessionClerk] = groupPopcornSize[myIndex];
		concessionClerkSodaToSell[myConcessionClerk] = groupSodaSize[myIndex];
		
		Signal(concessionClerkConditionVariable[myConcessionClerk], concessionClerkLock[myConcessionClerk]);
		ReleaseLock(concessionClerkBreakLock[myConcessionClerk]);
		Wait(concessionClerkConditionVariable[myConcessionClerk], concessionClerkLock[myConcessionClerk]);
		AcquireLock(concessionClerkBreakLock[myConcessionClerk]);
		
		/*STEP 2: Customer-ConcessionClerk, Customer hands out the cash*/
		
		Printing("Customer %i in Group %i in ConcessionClerk line \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
		Printing("%i is paying %i for food\n",  ConsoleOutput, myConcessionClerk, (groupPopcornSize[myIndex]*5 + groupSodaSize[myIndex]*4));

		groupMoney[myIndex] -= groupPopcornSize[myIndex]*5 + groupSodaSize[myIndex]*4;
		
		Signal(concessionClerkConditionVariable[myConcessionClerk], concessionClerkLock[myConcessionClerk]);
		ReleaseLock(concessionClerkBreakLock[myConcessionClerk]);
		Wait(concessionClerkConditionVariable[myConcessionClerk], concessionClerkLock[myConcessionClerk]);
		AcquireLock(concessionClerkBreakLock[myConcessionClerk]);
		
		/*STEP 3: Customer-ConcessionClerk, After the concession clerks sells the food, he takes the food*/
		Printing("Customer %i in Group %i is leaving \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
		Printing("ConcessionClerk%i\n", ConsoleOutput, myConcessionClerk, 0);
		
		/*TODO: Acknowledge that the purchase of food went through somehow.*/

		Signal(concessionClerkConditionVariable[myConcessionClerk], concessionClerkLock[myConcessionClerk]);
		
		/*printf("HCust%i: Im done buying food and to the Ticket Taker!\n", myIndex);*/
		ReleaseLock(concessionClerkBreakLock[myConcessionClerk]);
		ReleaseLock(concessionClerkLock[myConcessionClerk]);
	
		/*printf("HCust%i: I have $%i left in my wallet.\n", myIndex, groupMoney[myIndex]);*/
	}	
	
	/*END: Customer - ConcessionClerk Interaction*/
			
	/*BEGIN: Customer - TicketTaker Interaction*/
	
	while(1){
		myTicketTaker = -1; /* index = -1 */
		/*Printing("Customer %i Part 0\n", ConsoleOutput, headCustomerNumber[myIndex], 0);*/
		while(flag){
			/*printf("HCust%i: about to acquire ticket taker line lock to find a line\n", myIndex);*/
			/*Printing("Customer %i trying to acquire lock at index %i part 1\n", ConsoleOutput, headCustomerNumber[myIndex], ticketTakerLineLock);*/
			AcquireLock(ticketTakerLineLock);
			/*Printing("Customer %i acquired lock at index %i part 1\n", ConsoleOutput, headCustomerNumber[myIndex], ticketTakerLineLock);*/
			/*printf("HCust%i: acquired ticket taker line lock to find a line\n", myIndex);*/
			/* Look to find TixTaker that isnt busy */
			
			/*Printing("Customer %i Part 1\n", ConsoleOutput, headCustomerNumber[myIndex], 0);*/
			for(i = 0; i < MAX_TT; i++){
				/*Printing("Customer %i Part 1.1\n", ConsoleOutput, headCustomerNumber[myIndex], 0);*/
				if(ticketTakerState[i] == 0){
					/*Printing("Customer %i Part 1.2\n", ConsoleOutput, headCustomerNumber[myIndex], 0);*/
					myTicketTaker = i;
					ticketTakerState[i] = 1;
					Printing("Customer %i in Group %i is walking up to \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
					Printing("TicketTaker%i to give %i tickets.\n", ConsoleOutput, myTicketTaker, (groupSize[myIndex] + 1));
					flag = 0;
					break;
				}
			}
			
			/*Printing("Customer %i Part 2\n", ConsoleOutput, headCustomerNumber[myIndex], 0);*/
			
			/* TixTakers are all busy, will now look for shortest line */
			if(myTicketTaker == -1){
				/*printf("HCust%i: Finding the shortest ticket taker line\n", myIndex);*/
				shortestTicketTakerLine = 0; 
				shortestTicketTakerLineLength = ticketTakerLineCount[0];
				
				/*Printing("Customer %i Part 2.1\n", ConsoleOutput, headCustomerNumber[myIndex], 0);*/
				
				for(i = 0; i < MAX_TT; i++){
					if(ticketTakerState[i] == 1){
						AcquireLock(ticketTakerBreakLock[i]);
						if(ticketTakerBreak[i] == 0){
							shortestTicketTakerLine = i;
							shortestTicketTakerLineLength = ticketTakerLineCount[i];
						}
						ReleaseLock(ticketTakerBreakLock[i]);
					}
				}
				
				/*Printing("Customer %i Part 2.2\n", ConsoleOutput, headCustomerNumber[myIndex], 0);*/
				
				for(i = 1; i < MAX_TT; i++){
					if(ticketTakerState[i] == 1){
						AcquireLock(ticketTakerBreakLock[i]);
						if((shortestTicketTakerLineLength >= ticketTakerLineCount[i]) && ticketTakerBreak[i] == 0){
							/* Shorter line found, will now update shortest line */
							shortestTicketTakerLine = i;
							shortestTicketTakerLineLength = ticketTakerLineCount[i];
						}
						ReleaseLock(ticketTakerBreakLock[i]);
					}
				}
				
				/*Printing("Customer %i Part 2.3\n", ConsoleOutput, headCustomerNumber[myIndex], 0);*/
				
				/*printf("HCust%i: Getting in a ticket taker line\n", myIndex);*/
				myTicketTaker = shortestTicketTakerLine;
				Printing("Customer %i in Group %i is getting in \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
				Printing("TicketTaker line %i\n", ConsoleOutput, myTicketTaker, 0);
				ticketTakerLineCount[myTicketTaker]++;
				Wait(ticketTakerLineConditionVariable[myTicketTaker], ticketTakerLineLock);
				/*printf("HCust%i: reacquired TT%i ticket taker line lock after waiting in line going to check if hes on break\n", myIndex, myTicketTaker);*/
				
				/*Printing("Customer %i Part 2.4\n", ConsoleOutput, headCustomerNumber[myIndex], 0);*/
				
				AcquireLock(ticketTakerBreakLock[myTicketTaker]);
				if(ticketTakerBreak[myTicketTaker] == 1){
					Printing("Customer %i in Group %i sees \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
					Printing("TicketTaker %i is on break.\n", ConsoleOutput, myTicketTaker, 0);
					ticketTakerLineCount[myTicketTaker]--;
					
					ReleaseLock(ticketTakerLineLock);
					/*printf("HCust%i: released TT%i ticket taker line lock TTBreak == 1\n", myIndex, myTicketTaker);*/
					ReleaseLock(ticketTakerBreakLock[myTicketTaker]);
					
					myTicketTaker = -1;
				} else if (ticketTakerBreak[myTicketTaker] == 2){
					/*printf("HCust%i: my TT%i is taking too long, gotta find a new line\n", myIndex, myTicketTaker);*/
					ticketTakerLineCount[myTicketTaker]--;
					
					/*Printing("TicketTaker %i is taking too long. ticketTakerLineCount[%i] \0", ConsoleOutput, myTicketTaker, myTicketTaker);*/
					Printing("= %i\n", ConsoleOutput, ticketTakerLineCount[myTicketTaker]);
					if(ticketTakerLineCount[myTicketTaker] == 0){
						/*printf("HCust%i: TT%i line count == 0\n", myIndex, myTicketTaker);*/
						ticketTakerBreak[myTicketTaker] = 0;
					}
					
					ReleaseLock(ticketTakerLineLock);
					/*printf("HCust%i: released TT%i ticket taker line lock TTBreak == 2\n", myIndex, myTicketTaker);*/
					ReleaseLock(ticketTakerBreakLock[myTicketTaker]);
					
					myTicketTaker = -1;
				} else {
					/*printf("HCust%i: my TT%i isnt on break and doesnt have a huge line. onward!\n", myIndex, myTicketTaker);*/
					flag = 0;
					ReleaseLock(ticketTakerBreakLock[myTicketTaker]);
				}
				/* Cust is now in line waiting to be signaled to come to the counter */
				/*Printing("Customer %i end Part 2\n", ConsoleOutput, headCustomerNumber[myIndex], 0);*/
			}
		}
	
		/*Printing("Customer %i Part 3\n", ConsoleOutput, headCustomerNumber[myIndex], 0);*/
		
		flag = 1;
		/*printf("HCust%i: trying to release ticket taker line lock to start interaction\n", myIndex);*/
		ReleaseLock(ticketTakerLineLock);
		/*printf("HCust%i: released ticket taker line lock, trying to acquire TT%i ticket taker lock\n", myIndex, myTicketTaker);*/
		AcquireLock(ticketTakerLock[myTicketTaker]);
		/*printf("HCust%i: trying to acquire the TT%is break lock\n", myIndex, myTicketTaker);*/
		AcquireLock(ticketTakerBreakLock[myTicketTaker]);
		/*printf("HCust%i: acquired the TT%is break lock\n", myIndex, myTicketTaker);*/
		/*printf("HCust%i: TT%i ticket taker lock acquired\n", myIndex, myTicketTaker);*/
		/* Customer is now at counter */
		
		/*printf("HCust%i: Hello, TT%i I have %i tickets\n", myIndex, myTicketTaker, groupSize[myIndex]+1);*/
		ticketTakerCounter[myTicketTaker] = groupSize[myIndex]+1;
		
		Signal(ticketTakerConditionVariable[myTicketTaker], ticketTakerLock[myTicketTaker]);
		ReleaseLock(ticketTakerBreakLock[myTicketTaker]);
		/*printf("HCust%i: about to wait on TT%i ticket taker lock\n", myIndex, myTicketTaker);*/
		Wait(ticketTakerConditionVariable[myTicketTaker], ticketTakerLock[myTicketTaker]);
		/*printf("HCust%i: reacquired TT%i ticket taker lock\n", myIndex, myTicketTaker);*/
		/*AcquireLock(ticketTakerBreakLock[myTicketTaker]);*/
		
		/*ReleaseLock(ticketTakerBreakLock[myTicketTaker]);*/
		if(ticketTakerCounter[myTicketTaker] == 1){
			ticketTakerCounter[myTicketTaker] = -1;
			Signal(ticketTakerConditionVariable[myTicketTaker], ticketTakerLock[myTicketTaker]);
			Printing("Customer %i in Group %i is \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
			Printing("leaving TicketTaker%i\n", ConsoleOutput, myTicketTaker, 0);
			ReleaseLock(ticketTakerLock[myTicketTaker]);
			/*printf("HCust%i: released TT%i ticket taker lock\n", myIndex, myTicketTaker);*/
			break;
		} else {
			ticketTakerCounter[myTicketTaker] = -1;
			Signal(ticketTakerConditionVariable[myTicketTaker], ticketTakerLock[myTicketTaker]);
			/*printf("HCust%i: Why is TT%i such a negative nancy?\n", myIndex, myTicketTaker);*/
			ReleaseLock(ticketTakerLock[myTicketTaker]);
			/*printf("HCust%i: released TT%i ticket taker lock, trying to acquire ticket taker line lock\n", myIndex, myTicketTaker);*/
			/*Printing("Customer %i trying to acquire lock at index %i part 2\n", ConsoleOutput, headCustomerNumber[myIndex], ticketTakerLineLock);*/
			AcquireLock(ticketTakerLineLock);
			/*Printing("Customer %i acquired lock at index %i part 2\n", ConsoleOutput, headCustomerNumber[myIndex], ticketTakerLineLock);*/
			/*printf("\t\t\t\t\t\tHCust%i: going to the lobby\n", myIndex);*/
			Printing("Customer %i in Group %i sees TicketTaker \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
			Printing("%i is no longer taking tickets. Going to the lobby.\n", ConsoleOutput, myTicketTaker, 0);
			Printing("Customer %i in Group %i is in the lobby.\n", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
			Wait(lobbyConditionVariable, ticketTakerLineLock);
			Printing("Customer %i in Group %i is leaving the lobby.\n", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
			/*printf("HCust%i: reacquired TT%i ticket taker line lock, about to release\n", myIndex, myTicketTaker);*/
			ReleaseLock(ticketTakerLineLock);
			/*printf("HCust%i: released TT%i ticket taker line lock\n", myIndex, myTicketTaker);*/
		}
	}
	
	/*END: Customer - TicketTaker Interaction*/
	/* BEGIN: Customer - Movie Technician Interaction, finding a seat */
	/* 
	A.	find seats
	B.	wait for movie to start/finish
	C.	go bathroom, if needed
	*/
	/*printf("HCust%i: about to acquire movie room lock\n", myIndex);*/
	AcquireLock(movieRoomLock); /* Acquire the room lock */
	/*printf("HCust%i: acquired movie room lock about to acquire head customer lock\n", myIndex);*/
	AcquireLock(headCustomerLock[myIndex]);
	/*printf("HCust%i: i now have head customer lock and movie room lock\n", myIndex);*/
	
	/* 
	A. find seats 
		1.	find row that fits whole group
		2.	tell customers their seat numbers
		3.	add self to row
	*/
	foundRow = 0;
	for(i = 0; i < NUM_ROWS; i++){
		if((room[i] + groupSize[myIndex] + 1) <= ROW_SIZE){
			foundRow = 1; /* found row */
			seatNumber = room[i];
			for(j = 0; j < numCustomers; j++){


				if(myIndex == customerGroupNumber[j]){
					/*Rows are numbered with the tens digit = row, ones = column.
					So Seat 3 -> row 0, col 3.  Seat 14 -> row 1, col 4
					*/
					customerSeatNumber[j] = i*10+seatNumber;
					Printing("Customer %i in Group %i has found the following seat: \0", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
					Printing("row %i and seat %i\n", ConsoleOutput, i, seatNumber);
					
					if(customerIsHeadCustomer[j] == 1){
					/*	printf("HCust%i: Im in seat %i\n", myIndex, customerSeatNumber[j]);*/
					}
					
					seatNumber++;
					/*END: HeadCustomer-RegularCustomer Interaction, telling seats*/

				}
			}
			room[i] += (groupSize[myIndex] + 1); /* add group to row */
			seatsFilled += (groupSize[myIndex] + 1);

			break; /* dont need to keep checking for rows */
		}
	}
	
	/* if no row found
		1. disperse to any available seats
		this is really inefficient, perhaps a better way?
	*/
	if(foundRow == 0){
		tempGroupSize = (groupSize[myIndex] + 1);
		for(i = 0; i < NUM_ROWS; i++){
			if(tempGroupSize == 0){ /* the whole group is seated */
				break; 
			} else { /* whole group is not seated CHECK MATH HERE*/
				
				for(j = room[i]; j < ROW_SIZE; j++){ /* j = seatNumber */
					for(k = 0; k < numCustomers; k++){
						if(myIndex == customerGroupNumber[k] && customerSeatNumber[k] == -1){ /* if customer is in group and does not have a seat */
							customerSeatNumber[k] = i*10 + j;
							
							Printing("Customer %i in Group %i has found the following seat: \0", ConsoleOutput,headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
							Printing("row %i and seat %i\n", ConsoleOutput, i, j);

							
							if(customerIsHeadCustomer[k] == 1){
								/*printf("HCust%i: Im in seat %i\n", k, customerSeatNumber[k]);*/
							}
							/* ping pong with customer here */
							break; /* seat is filled */
						}
					}
					room[i] += tempGroupSize;
					tempGroupSize -= (ROW_SIZE - room[i]); /* people leave group to sit */
				}				
			}
		}
		
		/* group should all be seated at this point */
		seatsFilled += (groupSize[myIndex] + 1);
	}
	
	/*Telling all of the customers their seats.*/
	for(k = 0; k < groupSize[myIndex]; k++){
		Signal(regularCustomerConditionVariable[myIndex], headCustomerLock[myIndex]);
		/*printf("HCust%i: %i about to wait on head customer lock, just writing movie room lock\n", myIndex, groupSize[myIndex]);*/
		Wait(headCustomerConditionVariable[myIndex], headCustomerLock[myIndex]);
		/*printf("HCust%i: %i reacquired head customer lock, just writing movie room lock\n", myIndex, groupSize[myIndex]);*/
	}
	
	/* B. wait for movie to start and finish */
	/*printf("HCust%i: about to wait on movie room lock\n", myIndex);*/
	Wait(movieRoomConditionVariable, movieRoomLock);
	/*printf("HCust%i: reacquired movie room lock, about to release movie room lock\n", myIndex);*/
	ReleaseLock(movieRoomLock);
	/*printf("HCust%i: released movie room lock\n", myIndex);*/
	
	/* END: Customer finding a seat */
	
	/* BEGIN: Customers in the bathroom*/
	
	if(groupSize[myIndex] > 0){

		

		/*STEP 1: Asking each one if they need to go to the bathrrom*/
		for(i = 0; i < groupSize[myIndex]; i++){
			Signal(regularCustomerConditionVariable[myIndex], headCustomerLock[myIndex]);
			Wait(headCustomerConditionVariable[myIndex], headCustomerLock[myIndex]);
		}		

		AcquireLock(bathroomLock[myIndex]);
		customerNeedsBathroom[headCustomerNumber[myIndex]] = (Random()%4 > 0) ? 0 : 1;
		if(customerNeedsBathroom[headCustomerNumber[myIndex]]){
			/*printf("HCust%i: I need to go to the bathroom!\n",myIndex);*/
		}
		else{
			/*printf("HCust%i: I dont need to go to the bathroom!\n",myIndex);*/

		}
		
		ReleaseLock(bathroomLock[myIndex]);

		groupBathroomSize[myIndex] = 0;

		for(i = 0; i < numCustomers; i++){
			if(myIndex == customerGroupNumber[i]){
		
				if(customerNeedsBathroom[i]){
					Printing("Customer %i in Group %i is going to the bathroom.\n", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
					AcquireLock(bathroomLock[myIndex]);
					groupBathroomSize[myIndex]++;
					ReleaseLock(bathroomLock[myIndex]);
				}
			}
		}

		
		/*printf("HCust%i: Ill wait for %i people to go to the bathroon.\n",myIndex,groupBathroomSize[myIndex]);*/

	}
	else{
	
		customerNeedsBathroom[headCustomerNumber[myIndex]] = (Random()%4 > 0) ? 0 : 1;
		if(customerNeedsBathroom[headCustomerNumber[myIndex]]){
		
			for(i = 0; i < 20; i++){
				/*currentThread->Yield();*/
				Yield();
			}
		
		}
		
		groupBathroomSize[myIndex] = 0;

	}
	

	
	/*Step 2: Allowing the customers to go to the bathroom, or wait in the lobby*/
	for(i = 0; i < groupSize[myIndex]; i++){
	
			Signal(regularCustomerConditionVariable[myIndex], headCustomerLock[myIndex]);

			Wait(headCustomerConditionVariable[myIndex], headCustomerLock[myIndex]);
			
			

	}
	
	
	/*Step 3: Head customer goes to the lobby himself*/
	if(groupBathroomSize[myIndex] > 0 && groupSize[myIndex] > 0){

		AcquireLock(bathroomLock[myIndex]);
		
		groupBathroomSize[myIndex]--;
		
		ReleaseLock(bathroomLock[myIndex]);
		
		Printing("Customer %i in Group %i is leaving the bathroom.\n", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);

	}

	/* END: Customers going to the bathroom */
	
	AcquireLock(counterLock);
	custCounter -= 5;
	Printing("Customer %i in Group %i has left the movie theater.\n", ConsoleOutput, headCustomerNumber[myIndex], customerGroupNumber[headCustomerNumber[myIndex]]);
	ReleaseLock(counterLock);

	ReleaseLock(headCustomerLock[myIndex]);
	
	Exit(0);
}

void ticketClerk(){

	int myIndex;
	
	
	AcquireLock(ticketClerkIndexLock);
		myIndex = nextTicketClerk;
		nextTicketClerk++;
	ReleaseLock(ticketClerkIndexLock);


	while(1){ /* while true */
		/*Printing("TicketClerk %i\n", ConsoleOutput, myIndex, 0);*/
		/*Printing("ticketClerk %i acquiring lock &i\n", ConsoleOutput, myIndex, ticketClerkLineLock);*/
		AcquireLock(ticketClerkLineLock); /* Lock for choosing a line */
		/*printf("\tTC%i: line length:%i\n", myIndex, ticketClerkLineCount[myIndex]);*/
		/* check if there is a customer in my line */
		if(ticketClerkLineCount[myIndex] > 0){ /* There is someone in my line */
			/*printf("\tTC%i: Someone is in my line!\n", myIndex);*/
			/* Steps
			1. set my state to busy
			2. decrement line count
			3. wake up 1 customer */
			
			Printing("TicketClerk %i has a line length %i and is signaling a customer.\n", ConsoleOutput, myIndex, ticketClerkLineCount[myIndex]);
			ticketClerkState[myIndex] = 1; /* state = BUSY */
			ticketClerkLineCount[myIndex]--; /* decrement line count */
			Signal(ticketClerkLineConditionVariable[myIndex], ticketClerkLineLock);
		} else { /* no one is in my line */
			/* Steps
			1. set my state to not_busy */
			
			/*printf("\tTC%i: No one is in my line D:\n", myIndex);*/
			Printing("TicketClerk %i has no one in line. I am available for a customer.\n", ConsoleOutput, myIndex, 0);
			ticketClerkState[myIndex] = 0; /* state = NOT_BUSY */
		}
		
		/* done with clerks first monitor.
		   clerk is ready to wait
		   by acquiring the next lock before releasing the current lock,
		   we guarantee that we get the lock first */		
		AcquireLock(ticketClerkLock[myIndex]);
		/*printf("\tTC%i: releasing line lock and starting interaction\n", myIndex);*/
		ReleaseLock(ticketClerkLineLock);
		
		/*STEP 1: TicketClerk-Customer, Waiting for the customer to come up to ticket window so it can begin.*/		
		Wait(ticketClerkConditionVariable[myIndex], ticketClerkLock[myIndex]);
		
		Printing("TicketClerk %i ticketClerkState == %i\n", ConsoleOutput, myIndex, ticketClerkState[myIndex]);
		if(ticketClerkState[myIndex] != 0){
			/*STEP 2: TicketClerk-Customer, Tells Customer the total, and waits for the response (number of tickets)*/
			
			/*TODO: Check if customer can make a purchase?*/
			Printing("TicketClerk %i has an order for %i \0", ConsoleOutput, myIndex, ticketClerkNumToSell[myIndex]);
			Printing("and the cost is %i.\n", ConsoleOutput,ticketClerkNumToSell[myIndex]*12,0);
			Signal(ticketClerkConditionVariable[myIndex], ticketClerkLock[myIndex]);
			Wait(ticketClerkConditionVariable[myIndex], ticketClerkLock[myIndex]);
			
			/*STEP 3: TicketClerk-Customer, Takes cash from customer, puts in register.*/
			Printing("TicketClerk %i takes cash, puts in register.\n", ConsoleOutput,myIndex,0);
			ticketClerkRegister[myIndex] += ticketClerkNumToSell[myIndex]*12;
			
			ticketClerkNumToSell[myIndex] = 0; /*Resets to 0 inbetween transactions.*/
			
			Signal(ticketClerkConditionVariable[myIndex], ticketClerkLock[myIndex]);
			Wait(ticketClerkConditionVariable[myIndex], ticketClerkLock[myIndex]);
		}
		
		/*printf("\tTC%i: i have risen\n", myIndex);*/
		/*Printing("TC%i to acquire lock %i\n", ConsoleOutput, myIndex, ticketClerkBreakLock[myIndex]);*/
		AcquireLock(ticketClerkBreakLock[myIndex]);
		
		ReleaseLock(ticketClerkLock[myIndex]);

		if(ticketClerkBreak[myIndex] == 1){ /* i should go on break */
			/*printf("\tTC%i: trying to acquire the ticket clerk line lock, and i have the ticket clerk break lock\n", myIndex);*/
			/*AcquireLock(ticketClerkLineLock);*/
			/*printf("\tTC%i: ticket clerk line lock acquired\n", myIndex);*/
			/*ticketClerkLineCount[myIndex] = 0;*/
			/*Broadcast(ticketClerkLineConditionVariable[myIndex]ticketClerkLineLock);*/ /* signal to everyone in my line. need to acquire first???? MM: Yeah...Id say acquire.*/
			/*ReleaseLock(ticketClerkLineLock);*/
			/*printf("\tTC%i: ticket clerk line lock released\n", myIndex);*/
			Printing("TicketClerk %i is going on break.\n", ConsoleOutput, myIndex, 0);
			Wait(ticketClerkBreakConditionVariable[myIndex], ticketClerkBreakLock[myIndex]); /* wait until I am off break */
			Printing("TicketClerk %i is coming off break.\n", ConsoleOutput, myIndex, 0);
		}

		ReleaseLock(ticketClerkBreakLock[myIndex]);
	}
	
	Exit(0);
}

void concessionClerk(){
	
	int myIndex;
	
	AcquireLock(concessionClerkIndexLock);
		myIndex = nextConcessionClerk;
		nextConcessionClerk++;
	ReleaseLock(concessionClerkIndexLock);


	while(1){ 
	/* while true */
		/*Printing("ConcessionClerk %i\n", ConsoleOutput, myIndex, 0);*/
		AcquireLock(concessionClerkLineLock); /* Lock for choosing a line */
		/* check if there is a customer in my line */
		if(concessionClerkLineCount[myIndex] > 0){ /* There is someone in my line */
			/*printf("\t\tCC%i: Someone is in my line!\n", myIndex);*/
			/* Steps
			1. set my state to busy
			2. decrement line count
			3. wake up 1 customer */
			
			Printing("ConcessionClerk %i has a line length %i and is signaling a customer.\n", ConsoleOutput, myIndex, concessionClerkLineCount[myIndex]);
			concessionClerkState[myIndex] = 1; /* state = BUSY */
			concessionClerkLineCount[myIndex]--; /* decrement line count */
			Signal(concessionClerkLineConditionVariable[myIndex], concessionClerkLineLock);
		} else { /* no one is in my line */
			/* Steps
			1. set my state to not_busy */
			Printing("ConcessionClerk %i has no one in line. I am available for a customer.\n", ConsoleOutput, myIndex, 0);
			
			concessionClerkState[myIndex] = 0; /* state = NOT_BUSY */
		}
		
		/* done with concession clerks first monitor.
		   concession clerk is ready to wait
		   by acquiring the next lock before releasing the current lock,
		   we guarantee that we get the lock first */
		
		AcquireLock(concessionClerkLock[myIndex]);  
		ReleaseLock(concessionClerkLineLock);
		
		/*STEP 1: ConcessionClerk-Customer, Waiting for the customer to come up to the counter.*/
		/*printf("\t\tCC%i: Waiting for the customer to walk on up here!\n", myIndex);*/
		Wait(concessionClerkConditionVariable[myIndex], concessionClerkLock[myIndex]);
		
		if(concessionClerkState[myIndex] != 0){
			/*STEP 2: ConcessionClerk-Customer, Tells customer the total*/
			
			Printing("ConcessionClerk %i has an order for %i popcorn \0", ConsoleOutput, myIndex, concessionClerkPopcornToSell[myIndex]);
			Printing("and %i soda. The cost is %i.\n", ConsoleOutput, concessionClerkSodaToSell[myIndex], (concessionClerkPopcornToSell[myIndex]*5 + concessionClerkSodaToSell[myIndex]*4));

			Signal(concessionClerkConditionVariable[myIndex], concessionClerkLock[myIndex]);
			Wait(concessionClerkConditionVariable[myIndex], concessionClerkLock[myIndex]);
			
			/*STEP 3: ConcessionClerk-Customer, Takes cash from customer.*/
			concessionClerkRegister[myIndex] += (concessionClerkPopcornToSell[myIndex]*5 + concessionClerkSodaToSell[myIndex]*4);
			Printing("ConcessionClerk %i has been paid for the order.\n", ConsoleOutput, myIndex, 0);

			
			concessionClerkPopcornToSell[myIndex] = 0;
			concessionClerkSodaToSell[myIndex] = 0;
			
			Signal(concessionClerkConditionVariable[myIndex], concessionClerkLock[myIndex]);
			Wait(concessionClerkConditionVariable[myIndex], concessionClerkLock[myIndex]);
		}
		
		AcquireLock(concessionClerkBreakLock[myIndex]);
		
		ReleaseLock(concessionClerkLock[myIndex]);
		
		if(concessionClerkBreak[myIndex] == 1){ /* i should go on break */
			Printing("ConcessionClerk %i is going on break.\n", ConsoleOutput, myIndex, 0);
			/*AcquireLock(concessionClerkLineLock);*/
			/*concessionClerkLineCount[myIndex] = 0;*/
			/*Broadcast(concessionClerkLineConditionVariable[myIndex], concessionClerkLineLock);*/ /* signal to everyone in my line. need to acquire first???? */
			/*ReleaseLock(concessionClerkLineLock);*/
			Wait(concessionClerkBreakConditionVariable[myIndex], concessionClerkBreakLock[myIndex]); /* wait until I am off break */
			Printing("ConcessionClerk %i is coming off break.\n", ConsoleOutput, myIndex, 0);
		}

		ReleaseLock(concessionClerkBreakLock[myIndex]);
	}
	
	Exit(0);
}

void ticketTaker(){
	
	int myIndex;
	
	AcquireLock(ticketTakerIndexLock);
		myIndex = nextTicketTaker;
		nextTicketTaker++;
	ReleaseLock(ticketTakerIndexLock);

	while(1){
		/*printf("\t\t\tTT%i: about to acquire my ticket taker line lock\n", myIndex);*/
		/*Printing("TicketTaker %i\n", ConsoleOutput, myIndex, 0);*/
		/*Printing("TT %i trying to acquire lock at index %i\n", ConsoleOutput, myIndex, ticketTakerLineLock);*/
		AcquireLock(ticketTakerLineLock);  /* Look in line */
		/*Printing("TT %i acquired lock at index %i\n", ConsoleOutput, myIndex, ticketTakerLineLock);*/
		
		if(ticketTakerLineCount[myIndex] > 0){
			/*printf("\t\t\tTT%i: Someone is in my line!\n", myIndex);*/
			Printing("TicketTaker %i has a line length %i and is signaling a customer.\n", ConsoleOutput, myIndex, ticketTakerLineCount[myIndex]);
			ticketTakerState[myIndex] = 1;
			ticketTakerLineCount[myIndex]--;
			Signal(ticketTakerLineConditionVariable[myIndex], ticketTakerLineLock);
		} else {
			Printing("TicketTaker %i has no one in line. I am available for a customer.\n", ConsoleOutput, myIndex, 0);
			ticketTakerState[myIndex] = 0;
		}
		/*printf("\t\t\tTT%i: trying to acquire ticket taker lock\n", myIndex);*/
		AcquireLock(ticketTakerLock[myIndex]);
		/*printf("\t\t\tTT%i: acquired ticket taker lock about to release ticket taker line lock\n", myIndex);*/
		ReleaseLock(ticketTakerLineLock);
		/*printf("\t\t\tTT%i: released ticket taker line lock, about to wait on my ticket taker lock\n", myIndex);*/
		Wait(ticketTakerConditionVariable[myIndex], ticketTakerLock[myIndex]);
		/*printf("\t\t\tTT%i: reacquired my ticket taker lock\n", myIndex);*/
		
		if(ticketTakerState[myIndex] != 0){
			if(ticketTakerCounter[myIndex] <= ROW_SIZE*NUM_ROWS - numberAdmitted && movieStartTime == 0){
			/*if(ticketTakerCounter[myIndex] <= 10 - numberAdmitted && movieStartTime == 0){ testing purposes*/
				/* let them in */
				/*printf("\t\t\tTT%i: Youre good to go! Thanks brohan!\n", myIndex);*/
				
				Printing("TicketTaker %i has received %i tickets.\n", ConsoleOutput, myIndex, ticketTakerCounter[myIndex]);
				
				/*printf("\t\t\tTT%i: trying to acquire movie data lock\n", myIndex);*/
				AcquireLock(movieDataLock);
				/*printf("\t\t\tTT%i: acquired movie data lock\n", myIndex);*/
				numberAdmitted += ticketTakerCounter[myIndex];
				
				Printing("TicketTaker %i is allowing the group into the theater. The number of tickets taken is %i.\n", ConsoleOutput, myIndex, numberAdmitted);
				
				/*printf("\t\t\tTT%i: trying to release movie data lock\n", myIndex);*/
				ReleaseLock(movieDataLock);
				/*printf("\t\t\tTT%i: released movie data lock\n", myIndex);*/
				
				ticketTakerCounter[myIndex] = 1;
			} else {
				/* dont let them in */
				/*printf("\t\t\tTT%i: Sorry brochacho, cant let you in\n", myIndex);*/
				
				Printing("TicketTaker %i is not allowing the group into the theater. \0", ConsoleOutput, myIndex, numberAdmitted);
				Printing("The number of taken tickets is %i and the group size is %i.\n", ConsoleOutput, ticketTakerCounter[myIndex], 0);
				
				ticketTakerCounter[myIndex] = 0;
			}
		
			Signal(ticketTakerConditionVariable[myIndex], ticketTakerLock[myIndex]);
			/*printf("\t\t\tTT%i: Have a nice day!\n", myIndex);*/
			Wait(ticketTakerConditionVariable[myIndex], ticketTakerLock[myIndex]);
		}
		
		AcquireLock(ticketTakerBreakLock[myIndex]);
		
		/*printf("\t\t\tTT%i: reacquired my ticket taker lock, about to release ticket taker lock\n", myIndex);*/
		ReleaseLock(ticketTakerLock[myIndex]);
		/*printf("\t\t\tTT%i: released ticket taker lock, about to check for break stuff\n", myIndex);*/

		if(ticketTakerBreak[myIndex] == 1){ /* i should go on break */
			Printing("TicketTaker %i is going on break.\n", ConsoleOutput, myIndex, 0);
			/*AcquireLock(ticketTakerLineLock);*/
			/*ticketTakerLineCount[myIndex] = 0;*/
			/*Broadcast(ticketTakerLineConditionVariable[myIndex], ticketTakerLineLock);*/ /* signal to everyone in my line. need to acquire first???? */
			/*ReleaseLock(ticketTakerLineLock);*/
			Wait(ticketTakerBreakConditionVariable[myIndex], ticketTakerBreakLock[myIndex]); /* wait until I am off break */
			Printing("TicketTaker %i is coming off break.\n", ConsoleOutput, myIndex, 0);
		}

		ReleaseLock(ticketTakerBreakLock[myIndex]);
	}
	
	Exit(0);
}

void technician(){ 

/* doesnt really need an index but I put it because its necessary for forking and this will make it scalable if we want more technicians */
	
	int myIndex;
	int i;
	
	AcquireLock(technicianIndexLock);
		myIndex = nextTechnician;
		nextTechnician++;
	ReleaseLock(technicianIndexLock);
	
	while(1){
		/*Printing("Technician %i\n", ConsoleOutput, myIndex, 0);*/
		/* 
		A.	if movie conditions met, start movie
		B.	tell customers to leave room
		C.	wait for next movie data
		*/
		/*printf("\t\t\t\tMT: about to acquire the movie lock\n");*/
		AcquireLock(movieDataLock);
		/*printf("\t\t\t\tMT: acquired the movie lock, trying to acquire movie room lock\n");*/
		
		/* A. if movie conditions met, start movie
			1.	check if current time is movie start time
			2.	check if all sold tickets are accounted for
		*/
		AcquireLock(movieRoomLock);
		/*printf("\t\t\t\tMT: acquired the movie room lock\n");*/
		
		/*printf("\t\t\t\tMT: checking if I can play movie\n");*/
		if(movieStartTime == 1 && seatsFilled == numberAdmitted){ /* remove the && bit later */
			numberAdmitted = 0; 
			
			movieLength = Random() % 100 + 200;
			movieLength = 300;
			
			Printing("The MovieTechnician has started the movie.\n", ConsoleOutput, 0, 0);
			
		/*	printf("\t\t\t\tMT: playing dat movie, I love Matt Damon. its %i long\n", movieLength);*/
			for(i = 0; i < movieLength; i++){
				/*currentThread->Yield();*/ /* used to play movie */
				Yield();
			}
			
			
			
			/* movie should be done at this point */
			seatsFilled = 0; 
			movieStartTime = 0;
			movieEnded = 1;
			/* B. tell customers to leave room */
			Printing("The MovieTechnician has ended the movie.\n", ConsoleOutput, 0, 0);
			
			for(i = 0; i < NUM_ROWS; i++){
				room[i] = 0;
			}
			Broadcast(movieRoomConditionVariable, movieRoomLock);
			Printing("The MovieTechnician has told all customers to leave the theater room.\n", ConsoleOutput, 0, 0);
		}
		/*printf("\t\t\t\tMT: about to release movie room lock\n");*/
		ReleaseLock(movieRoomLock);
		/* C. wait for next movie data */
		/*printf("\t\t\t\tMT: released movie room lock, waiting for my movie data\n");*/
		Wait(technicianDataConditionVariable, movieDataLock);
		/*printf("\t\t\t\tMT: reacquired and now about to release movie data lock\n");*/
		ReleaseLock(movieDataLock);
		/*printf("\t\t\t\tMT: released movie data lock\n");*/
	}
	
	Exit(0);
}

void manager(){
	int myIndex;
	int counter = 0;
	int i;
	int j;
	int temp;
	
	while(1){
		/*printf("\t\t\t\t\tMANAGER\n");*/
		/* BEGIN: ON BREAK STUFF */

		/* tell the ticket clerk to go on break if need be */
		/* acquire the ticket clerk line lock to see state? */
		/*Printing("Manager trying to acquire lock %i\n", ConsoleOutput, ticketClerkLineLock, 0);*/
		AcquireLock(ticketClerkLineLock);
		/*Printing("Manager acquired lock %i\n", ConsoleOutput, ticketClerkLineLock, 0);*/
		
		/*printf("\t\t\t\t\tMAN: check if any TCs need a break.\n");*/
		for(i = 0; i < MAX_TC; i++){
			if(ticketClerkState[i] == 1 || ticketClerkState[i] == 0){ /* if available */
				/*printf("\t\t\t\t\tMAN: acquiring TC%is break lock\n", i);*/
				AcquireLock(ticketClerkBreakLock[i]);
				
				if(ticketClerkLineCount[i] < 3){ /* if line size is < 3 */
					/*Printing("ticketClerkLineCount[%i] < 3\n", ConsoleOutput, i, i);*/
					for(j = 0; j < MAX_TC; j++){
						if(j != i && ticketClerkState[j] > -1 && ticketClerkBreak[j] == 0 && ticketClerkBreak[i] == 0){ /* if there is another clerk available */
							/*Printing("inside the if statement [%i] [%i]\n", ConsoleOutput, i, j);*/
							if(Random() % 100 < 20){
								Printing("Manager has told TicketClerk %i to go on break.\n", ConsoleOutput, i, 0);
								/*printf("\t\t\t\t\tMAN: TC%i has %i in his line, take a break!\n", i, ticketClerkLineCount[i]);*/
								/*ticketClerkLineCount[i] = 0;*/
								Broadcast(ticketClerkLineConditionVariable[i], ticketClerkLineLock);
								if(ticketClerkState[i] == 0){
									Signal(ticketClerkConditionVariable[i], ticketClerkLock[i]);
								}
								ticketClerkState[i] = 2; /* set to "break" MM: I think you should preserve the state as not busy. */
								ticketClerkBreak[i] = 1; /* set them to on break */	
								/*currentThread->Yield();*/
								/*Yield();*/
								break;
							}
						}
					}
				} else if(ticketClerkLineCount[i] > 5){
					for(j = 0; j < MAX_TC; j++){
						if(j != i && ticketClerkBreak[j] == 1 && 0){
							/*printf("\t\t\t\t\tMAN: TC%i get off break, TC%i is getting slammed with %i!\n", j, i, ticketClerkLineCount[i]);*/
							Printing("Manager has told TicketClerk %i to go off break.\n", ConsoleOutput, i, 0);
							Broadcast(ticketClerkLineConditionVariable[i], ticketClerkLineLock);
							ticketClerkBreak[i] = 2; /* tell line to leave */
							/*ticketClerkLineCount[i] = 0;*/
							ticketClerkLineCount[j] = 0;
							ticketClerkState[j] = 0; /* set to not busy */
							ticketClerkBreak[j] = 0; /* set them to off break */
							Signal(ticketClerkBreakConditionVariable[j], ticketClerkBreakLock[j]); /* signal to come off break gets signalled even if the ticket clerk isnt waiting for on break...need to fix!*/
							/*currentThread->Yield();*/
							/*Yield();*/
							break;
						}
					}			
				}
				
				/*printf("\t\t\t\t\tMAN: releasing TC%is break lock\n", i);*/
				ReleaseLock(ticketClerkBreakLock[i]);
				/*Yield();*/
			}
		}

		/* tell the concession clerk to go on break if need be */
		/* acquire the concession clerk line lock to see state? */
		/*printf("\t\t\t\t\tMAN: trying to acquire concession clerk line lock\n");*/
		AcquireLock(concessionClerkLineLock);
		
		/*printf("\t\t\t\t\tMAN: done checking TCs for breaks\n");*/
		ReleaseLock(ticketClerkLineLock);

		/*printf("\t\t\t\t\tMAN: check if any CCs need a break.\n");*/
		for(i = 0; i < MAX_CC; i++){
			if(concessionClerkState[i] == 1 || concessionClerkState[i] == 0){ /* if available */
				AcquireLock(concessionClerkBreakLock[i]);
				
				if(concessionClerkLineCount[i] < 3){ /* if line size is < 3 */
					for(j = 0; j < MAX_TC; j++){
						if(j != i && concessionClerkState[j] > -1 && concessionClerkBreak[j] == 0 && concessionClerkBreak[i] == 0){ /* if there is another clerk available */
							if(Random() % 100 < 20){
								/*printf("\t\t\t\t\tMAN: CC%i has %i in his line, take a break!\n", i, concessionClerkLineCount[i]);*/
								Printing("Manager has told ConcessionClerk %i to go on break.\n", ConsoleOutput, i, 0);
								/*concessionClerkLineCount[i] = 0;*/
								Broadcast(concessionClerkLineConditionVariable[i], concessionClerkLineLock);
								if(concessionClerkState[i] == 0){
									Signal(concessionClerkConditionVariable[i], concessionClerkLock[i]);
								}
								concessionClerkState[i] = 2; /* set to "break" */
								concessionClerkBreak[i] = 1; /* set them to on break */
								/*currentThread->Yield();*/
								/*Yield();*/
								break;
							}
						}
					}
				} else if(concessionClerkLineCount[i] > 5){
					for(j = 0; j < MAX_TC; j++){
						if(j != i && concessionClerkBreak[j] == 1 && 0){
							/*printf("\t\t\t\t\tMAN: CC%i get off break, CC%i is getting slammed with %i!\n", j, i, concessionClerkLineCount[i]);*/
							Broadcast(concessionClerkLineConditionVariable[i], concessionClerkLineLock);
							concessionClerkBreak[i] = 2; /* tell line to leave */
							/*concessionClerkLineCount[i] = 0;*/
							concessionClerkLineCount[j] = 0;
							concessionClerkState[j] = 0; /* set to not busy */
							concessionClerkBreak[j] = 0; /* set them to off break */
							Signal(concessionClerkBreakConditionVariable[j], concessionClerkBreakLock[j]); /* signal to come off break */
							/*currentThread->Yield();*/
							/*Yield();*/
							break;
						}
					}			
				}
				
				ReleaseLock(concessionClerkBreakLock[i]);
				/*Yield();*/
			}
		}

		/* tell the ticket taker to go on break if need be */
		/* acquire the ticket taker line lock to see state? */
		/*printf("\t\t\t\t\tMAN: trying to acquire ticket taker line lock to check for breaks\n");*/
		AcquireLock(ticketTakerLineLock);

		/*printf("\t\t\t\t\tMAN: done checking CCs for breaks\n");*/
		ReleaseLock(concessionClerkLineLock);

		/*printf("\t\t\t\t\tMAN: acquired ticket taker line lock to check for breaks\n");*/

		/*printf("\t\t\t\t\tMAN: check if any TTs need a break.\n");*/
		for(i = 0; i < MAX_TT; i++){
			if(ticketTakerState[i] == 1 || ticketTakerState[i] == 0){ /* if available */
				/*printf("\t\t\t\t\tMAN: trying to acquire TT%is break lock\n", i);*/
				AcquireLock(ticketTakerBreakLock[i]);
				/*printf("\t\t\t\t\tMAN: acquired TT%is break lock\n", i);*/
				
				if(ticketTakerLineCount[i] < 3){ /* if line size is < 3 */
					for(j = 0; j < MAX_TT; j++){
						if(j != i && ticketTakerState[j] > -1 && ticketTakerBreak[j] == 0 && ticketTakerBreak[i] == 0){ /* if there is another taker available */
							if(Random() % 100 < 20){
								/*printf("\t\t\t\t\tMAN: TT%i has %i in his line, take a break!\n", i, ticketTakerLineCount[i]);*/
								
								Printing("Manager has told TicketTaker %i to go on break.\n", ConsoleOutput, i, 0);
								/*ticketTakerLineCount[i] = 0;*/
								Broadcast(ticketTakerLineConditionVariable[i], ticketTakerLineLock);
								if(ticketTakerState[i] == 0){
									Signal(ticketTakerConditionVariable[i], ticketTakerLock[i]);
								}
								ticketTakerState[i] = 2; /* set to "break" */
								ticketTakerBreak[i] = 1; /* set them to on break */
								/*currentThread->Yield();*/
								/*Yield();*/
								break;
							}
						}
					}
				} else if(ticketTakerLineCount[i] > 5){
					for(j = 0; j < MAX_TT; j++){
						if(j != i && ticketTakerBreak[j] == 1 && 0){
							/*printf("\t\t\t\t\tMAN: TT%i get off break, TT%i is getting slammed with %i!\n", j, i, ticketTakerLineCount[i]);*/
							Broadcast(ticketTakerLineConditionVariable[i], ticketTakerLineLock);
							ticketTakerBreak[i] = 2; /* tell line to leave */
							/*ticketTakerLineCount[i] = 0;*/
							ticketTakerLineCount[j] = 0;
							ticketTakerState[j] = 0; /* set to not busy */
							ticketTakerBreak[j] = 0; /* set them to off break */
							Signal(ticketTakerBreakConditionVariable[j], ticketTakerBreakLock[j]); /* signal to come off break */
							/*currentThread->Yield();*/
							/*Yield();*/
							break;
						}
					}			
				}
				
				ReleaseLock(ticketTakerBreakLock[i]);
				/*Yield();*/
			}
		}

		/*printf("\t\t\t\t\tMAN: about to release ticket taker line lock after checking for breaks\n*/
		/*ReleaseLock(ticketTakerLineLock);*/
		/*printf("\t\t\t\t\tMAN: released ticket taker line lock after checking for breaks\n");*/
		
		/* END: ON BREAK STUFF */
	
		/*printf("\t\t\t\t\tMAN: trying to acquire movie data lock\n");*/
		AcquireLock(movieDataLock);
		/*printf("\t\t\t\t\tMAN: acquired movie data lock\n");*/
		/* lock all the ticket takers */
		/*printf("\t\t\t\t\tMAN: trying to acquire ticket taker line lock to acquire ticket taker locks\n");*/
		/*AcquireLock(ticketTakerLineLock);*/ /* checking ticketTakerStates */
		/*printf("\t\t\t\t\tMAN: acquired ticket taker line lock to acquire ticket taker locks\n");*/
		for(i = 0; i < MAX_TT; i++){
			if(ticketTakerState[i] > -1){
				/*printf("\t\t\t\t\tMAN: trying to acquire TT%i taker lock\n", i);*/
				AcquireLock(ticketTakerLock[i]);
				/*printf("\t\t\t\t\tMAN: acquired TT%i taker lock\n", i);*/
			}
		}
		/*printf("\t\t\t\t\tMAN: about to release ticket taker line lock after acquiring ticket taker locks\n");*/
		/*ReleaseLock(ticketTakerLineLock);*/
		/*printf("\t\t\t\t\tMAN: released ticket taker line lock after acquiring ticket taker locks\n");*/
		
		/*printf("\t\t\t\t\tMAN: can we start the movie? startNumber:%i, numberAdmitted:%i; seatsFilled:%i; movieStartTime:%i; counter:%i\n", NUM_ROWS*ROW_SIZE - 3, numberAdmitted, seatsFilled, movieStartTime, counter);*/
		Printing("Manager is checking to start a movie. numberAdmitted = %i; seatsFilled = %i\n", ConsoleOutput, numberAdmitted, seatsFilled);
		Printing("movieStartTime = %i; counter = %i\n", ConsoleOutput, movieStartTime, counter);
		if(numberAdmitted == seatsFilled && movieStartTime == 0 && seatsFilled != 0 && numberAdmitted > NUM_ROWS*ROW_SIZE - 3 || (counter > 100 && numberAdmitted > 0 && numberAdmitted == seatsFilled)){ /*if people have been waiting in the theater for a while, start the movie*/
			/*printf("\t\t\t\t\tMAN: yo lets get this partay started!\n");*/
			Printing("Manager is telling the MovieTechnnician to start the movie.\n", ConsoleOutput, 0, 0);
			Signal(technicianDataConditionVariable, movieDataLock);
			movieEnded = 0;
			movieStartTime = 1;
			
			/* check the ticket clerk registers */
			/*printf("\t\t\t\t\tMAN: checking the ticket clerk registers\n");*/
			for(i = 0; i < MAX_TC; i++){
				/*printf("\t\t\t\t\tMAN: acquiring line lock before reading registers\n");*/
				/*Printing("Manager checking lock %i for registers\n", ConsoleOutput, ticketClerkLineLock, 0);*/
				AcquireLock(ticketClerkLineLock);
				if(ticketClerkState[i] > -1){
					AcquireLock(ticketClerkLock[i]);
					ticketMoney += ticketClerkRegister[i];
					Printing("Manager collected %i from TicketClerk%i.\n", ConsoleOutput, ticketClerkRegister[i], i);
					ticketClerkRegister[i] = 0;
					ReleaseLock(ticketClerkLock[i]);
				}
				/*printf("\t\t\t\t\tMAN: releasing line lock after reading registers\n");*/
				ReleaseLock(ticketClerkLineLock);
			}
			/*printf("\t\t\t\t\tMAN: we have made $%i so far from tickets\n", ticketMoney);*/
			
			/* check the concession clerk registers */
			/*printf("\t\t\t\t\tMAN: checking the concession clerk registers\n");*/
			for(i = 0; i < MAX_CC; i++){
				AcquireLock(concessionClerkLineLock);
				if(concessionClerkState[i] > -1){
					AcquireLock(concessionClerkLock[i]);
					concessionMoney += concessionClerkRegister[i];
					Printing("Manager collected %i from ConcessionClerk%i.\n", ConsoleOutput, concessionClerkRegister[i], i);
					concessionClerkRegister[i] = 0;
					ReleaseLock(concessionClerkLock[i]);
				}
				ReleaseLock(concessionClerkLineLock);
			}
			
			Printing("Total money made by office = %i \n", ConsoleOutput, (ticketMoney + concessionMoney), 0);
			
			/*printf("\t\t\t\t\tMAN: we have made $%i so far from concessions\n", concessionMoney);	*/		
		}
		
		/*printf("\t\t\t\t\tMAN: i forget, did a movie just finish?\n");*/
		if(movieEnded == 1){
		/*	printf("\t\t\t\t\tMAN: movies over! people can line up again\n");*/
			counter = 0;
			movieStartTime = 0;
			movieEnded = 0;
			/*printf("\t\t\t\t\tMAN: about to acquire ticket taker line lock for broadcast\n");*/
			/*AcquireLock(ticketTakerLineLock);*/
			/*printf("\t\t\t\t\tMAN: acquired ticket taker line lock for broadcast\n");*/
			/*printf("\t\t\t\t\tMAN: broadcast\n");*/
			Broadcast(lobbyConditionVariable, ticketTakerLineLock);
			/*printf("\t\t\t\t\tMAN: about to release ticket taker line lock for broadcast\n");*/
			/*ReleaseLock(ticketTakerLineLock);*/
			/*printf("\t\t\t\t\tMAN: released ticket taker line lock for broadcast\n");*/
		}
		
		/* release all the ticket clerks */
		/*printf("\t\t\t\t\tMAN: trying to acquire ticket taker line lock to release ticket taker locks\n");*/
		/*AcquireLock(ticketTakerLineLock);*/ /* checking ticketTakerStates */
		/*printf("\t\t\t\t\tMAN: acquired ticket taker line lock to release ticket taker locks\n");*/
		for(i = 0; i < MAX_TT; i++){
			if(ticketTakerState[i] > -1){
				/*printf("\t\t\t\t\tMAN: releasing TT%is taker lock\n", i);*/
				ReleaseLock(ticketTakerLock[i]);
				/*printf("\t\t\t\t\tMAN: released TT%is taker lock\n", i);*/
			}
		}
		
		AcquireLock(counterLock);
		
		/*printf("\t\t\t\t\tMAN: about to release ticket taker line lock to release ticket taker locks\n");*/
		ReleaseLock(ticketTakerLineLock);
		/*printf("\t\t\t\t\tMAN: released ticket taker line lock to release ticket taker locks\n");*/
		
		/*printf("\t\t\t\t\tMAN: Waiting yo\n");*/
		/*Wait(technicianDataConditionVariable, movieDataLock);*/
		/*printf("\t\t\t\t\tMAN: about to release movie data lock\n");*/
		ReleaseLock(movieDataLock);
		/*printf("\t\t\t\t\tMAN: released movie data lock\n");*/
		
		
		/*printf("\t\t\t\t\tMAN: custCounter = %i\n", custCounter);*/
		Printing("custCounter = %i\n", ConsoleOutput, custCounter, 0);
		temp = custCounter;
		ReleaseLock(counterLock);
		
		if(temp == 0){
			Printing("Total money made by office = %i \n", ConsoleOutput, (ticketMoney + concessionMoney), 0);
			/*printf("\t\t\t\t\tMAN: closing shop, no customers left\n")*/
			/*printf("\t\t\t\t\tMAN: we have made $%i from tickets\n", ticketMoney);*/
			/*printf("\t\t\t\t\tMAN: we have made $%i from concessions\n", concessionMoney);*/
			break;
		}
		
		counter++;
		/*currentThread->Yield();*/
		Yield();
	}
	Exit(0);
}

void theaterInitializations(int numTC, int numCC, int numTT, int maxCust)
{

	int i;
	int customersLeft;
	int numFriends;
	int j;

   /* DEBUG('t', "Entering Movie Theater Simulation");*/

	Printing("Movie Theater Simulation\n", ConsoleOutput, 0, 0);
	Printing("***\n", ConsoleOutput, 0, 0);
	
	custCounter = maxCust;

	counterLock = CreateLock(); /* 0 */
	/*Printing("counterLock = %i\n", ConsoleOutput, counterLock, 0);*/
	
	/*Begin: Index Locks*/
	
	regularCustomerIndexLock = CreateLock(); /* 1 */
	/*Printing("regularCustomerIndexLock = %i\n", ConsoleOutput, regularCustomerIndexLock, 0);*/
	headCustomerIndexLock = CreateLock(); /* 2 */
	/*Printing("headCustomerIndexLock = %i\n", ConsoleOutput, headCustomerIndexLock, 0);*/
	ticketClerkIndexLock = CreateLock(); /* 3 */
	/*Printing("ticketClerkIndexLock = %i\n", ConsoleOutput, ticketClerkIndexLock, 0);*/
	concessionClerkIndexLock = CreateLock(); /* 4 */
	/*Printing("concessionClerkIndexLock = %i\n", ConsoleOutput, concessionClerkIndexLock, 0);*/
	ticketTakerIndexLock = CreateLock(); /* 5 */
	/*Printing("ticketTakerIndexLock = %i\n", ConsoleOutput, ticketTakerIndexLock, 0);*/
	technicianIndexLock = CreateLock(); /* 6 */
	/*Printing("technicianIndexLock = %i\n", ConsoleOutput, technicianIndexLock, 0);*/
	
	/*End: Index Locks*/
	
	/*BEGIN: Ticket Clerk Initialization*/
	
	ticketClerkLineLock = CreateLock(); /* 7 */
	/*Printing("ticketClerkLineLock = %i\n", ConsoleOutput, ticketClerkLineLock, 0);*/
	
	for(i = 0; i < MAX_TC; i++){
		
		if(i < numTC ){
		
			ticketClerkLineConditionVariable[i] = CreateCondition();
			ticketClerkLineCount[i] = 0;		
			ticketClerkLock[i] = CreateLock();
			/*Printing("ticketClerkLock[%i] = %i\n", ConsoleOutput, i, ticketClerkLock[i]);*/
			ticketClerkConditionVariable[i] = CreateCondition();
			ticketClerkRegister[i] = 0;
			ticketClerkState[i] = 0;
			
			ticketClerkBreakLock[i] = CreateLock();
			/*Printing("ticketClerkBreakLock[%i] = %i\n", ConsoleOutput, i, ticketClerkBreakLock[i]);*/
			ticketClerkBreakConditionVariable[i] = CreateCondition();
			ticketClerkBreak[i] = 0;
			
			/*Thread *t = new Thread("TicketClerk thread");*/
			/*t->Fork(ticketClerk, i);*/
		
		}
		else{
			ticketClerkLineCount[i] = 0;	
			ticketClerkState[i] = -1;				
		}
	
	}
	
	/*END: Ticket Clerk Initialization*/
	
	/*BEGIN: Concession Clerk Initialization*/
	
	concessionClerkLineLock = CreateLock();
	/*Printing("concessionClerkLineLock = %i\n", ConsoleOutput, concessionClerkLineLock, 0);*/
	
	for(i = 0; i < MAX_CC; i++){
		
		if(i < numCC ){
		
			concessionClerkLineConditionVariable[i] = CreateCondition();
			concessionClerkLineCount[i] = 0;		
			concessionClerkLock[i] = CreateLock();
			/*Printing("concessionClerkLock[%i] = %i\n", ConsoleOutput, i, concessionClerkLock[i]);*/
			concessionClerkConditionVariable[i] = CreateCondition();
			concessionClerkRegister[i] = 0;
			concessionClerkState[i] = 0;
			
			concessionClerkBreakLock[i] = CreateLock();
			/*Printing("concessionClerkBreakLock[%i] = %i\n", ConsoleOutput, i, concessionClerkBreakLock[i]);*/
			concessionClerkBreakConditionVariable[i] = CreateCondition();
			concessionClerkBreak[i] = 0;
			
			/*Thread *t = new Thread("ConcessionClerk thread");*/
			/*t->Fork(concessionClerk, i);*/
		
		}
		else{
			concessionClerkLineCount[i] = 0;
			concessionClerkState[i] = -1;				
		}
	
	}
	
	/*END: Concession Clerk Initialization*/
	
	/*BEGIN: Ticket Taker Intializations*/
	
	ticketTakerLineLock = CreateLock();
	/*Printing("ticketTakerLineLock = %i\n", ConsoleOutput, ticketTakerLineLock, 0);*/
	
	/*numberAdmitted = 0;*/
	for(i = 0; i < MAX_TT; i++){
		
		/* will now initialize for number of TixTakers */
		if(i < numTT){
			ticketTakerLineConditionVariable[i] = CreateCondition();
			ticketTakerConditionVariable[i] = CreateCondition();
			ticketTakerLineCount[i] = 0;
			ticketTakerCounter[i] = 0;
			ticketTakerState[i] = 0;
			ticketTakerLock[i] = CreateLock();
			/*Printing("ticketTakerLock[%i] = %i\n", ConsoleOutput, i, ticketTakerLock[i]);*/
			
			ticketTakerBreakLock[i] = CreateLock();
			/*Printing("ticketTakerBreakLock[%i] = %i\n", ConsoleOutput, i, ticketTakerBreakLock[i]);*/
			ticketTakerBreakConditionVariable[i] = CreateCondition();
			ticketTakerBreak[i] = 0;
			
			/*Thread *t = new Thread("TicketTaker thread");*/
			/*t->Fork(ticketTaker, i);*/
			
		} else {
			ticketTakerState[i] = -1;
			ticketTakerLineCount[i] = 0;
		}
	}
	
		/* Lobby */
	lobbyConditionVariable = CreateCondition();
	
	/*END: Ticket Taker Initializations*/
	
	/* BEGIN: Technician Initialization */
	
	for(i = 0; i < NUM_ROWS; i++){
		room[i] = 0; 
	}
	
	movieRoomLock = CreateLock();
	/*Printing("movieRoomLock = %i\n", ConsoleOutput, movieRoomLock, 0);*/
	movieRoomConditionVariable = CreateCondition();
	
	movieDataLock = CreateLock();
	/*Printing("movieDataLock = %i\n", ConsoleOutput, movieDataLock, 0);*/
	technicianDataConditionVariable = CreateCondition();
	
	/*Thread *tempThread = new Thread("Technician Thread");*/
	/*tempThread->Fork(technician, 0);*/
	
	/* END: Technician Initialization */	
	
	/*BEGIN: Manager Initializations*/
	
	movieLength = 0;
	movieStartTime = 0;
	movieEnded = 0;
	
	/*tempThread = new Thread("Manager Thread");*/
	/*tempThread->Fork(manager, 0);*/
	
	/*END: Manager Initializations*/
	
	/*BEGIN: Customer Initialization*/
	
	customersLeft = maxCust;
	
	numCustomers = 0;
	
	for (i=0; i < maxCust; i++ ) {
		
		/*Generate the size of the group, not counting head customer*/
		numFriends =  4;
		/*int numFriends = Random() % 5;*/

		if(customersLeft <= 0){
			numGroups = i;
			break;
		}
		
		if(customersLeft <= numFriends){
			numFriends = customersLeft - 1;
		}

		if(customersLeft > 0){
			/*Head Customers Regular Customer Data (because hes a customer too)*/
			customerNumber[numCustomers] = numCustomers;
			customerGroupNumber[numCustomers] = i;
			customerWantsPopcorn[numCustomers] = -1;
			customerWantsSoda[numCustomers] = -1;
			customerNeedsBathroom[numCustomers] = -1;
			customerIsHeadCustomer[numCustomers] = 1;
			customerSeatNumber[numCustomers] = -1;
			customerHasPopcorn[numCustomers] = -1;
			customerHasSoda[numCustomers] = -1;
			
			/* Head Customer Data */		
			groupSize[i] = numFriends;
			numFriendsLeft[i] = numFriends;
			groupPopcornSize[i] = -1;
			groupSodaSize[i] = -1;
			groupBathroomSize[i] = -1;
			groupMoney[i] = 105;
			groupTickets[i] = -1;
			headCustomerNumber[i] = numCustomers;
			customerState[i] = -1;
			customerStateLock[i] = CreateLock();
			/*Printing("customerStateLock[%i] = %i\n", ConsoleOutput, i, customerStateLock[i]);*/
			
			/*Thread *t = new Thread("Head Customer");*/
			/*t->Fork( headCustomer, i);*/
			
			headCustomerLock[i] = CreateLock();
			/*Printing("headCustomerLock[%i] = %i\n", ConsoleOutput, i, headCustomerLock[i]);*/
		
			headCustomerConditionVariable[i] = CreateCondition();
			regularCustomerConditionVariable[i] = CreateCondition();
		
			numCustomers++;
			
			bathroomLock[i] = CreateLock();
			/*Printing("bathroomLock[%i] = %i\n", ConsoleOutput, i, bathroomLock[i]);*/
			bathroomLobbyConditionVariable[i] = CreateCondition();
			
			/*Now make all the regular Customers for this group*/
			for (j = 0; j < numFriends; j++ ) {
				
				customerNumber[numCustomers] = numCustomers;
				customerGroupNumber[numCustomers] = i;
				customerWantsPopcorn[numCustomers] = -1;
				customerWantsSoda[numCustomers] = -1;
				customerNeedsBathroom[numCustomers] = -1;
				customerIsHeadCustomer[numCustomers] = 0;
				customerSeatNumber[numCustomers] = -1;
				customerHasPopcorn[numCustomers] = -1;
				customerHasSoda[numCustomers] = -1;
							
				/*t = new Thread("Regular Customer");*/
				/*t->Fork( regularCustomer, numCustomers );*/
				
				
				
				numCustomers++;
			}
		
			customersLeft -= (numFriends + 1);		
		
		}	
	}

	/*END: Customer Initialization*/
	
	Printing("Number of Customers = %i\n", ConsoleOutput, maxCust, 0);
	Printing("Number of Groups = %i\n", ConsoleOutput, numGroups, 0);
	Printing("Number of TicketClerks = %i\n", ConsoleOutput, numTC, 0);
	Printing("Number of ConcessionClerks = %i\n", ConsoleOutput, numCC, 0);
	Printing("Number of TicketTakers = %i\n", ConsoleOutput, numTT, 0);
	
	Printing("***\n", ConsoleOutput, 0, 0);
	
	/* BEGIN: Forking Threads */
	/* ticket clerk forking */
	for(i = 0; i < MAX_TC; i++){
		if(i < numTC){
			/*Thread *t = new Thread("TicketClerk thread");*/
			/*t->Fork(ticketClerk, i);*/
			Fork(ticketClerk);
		}
	}
	
	/* concession clerk forking */
	for(i = 0; i < MAX_CC; i++){
		if(i < numCC){
			/*Thread *t = new Thread("ConcessionClerk thread");*/
			/*t->Fork(concessionClerk, i);*/
			Fork(concessionClerk);
		}
	}
	
	/* ticket taker forking */
	for(i = 0; i < MAX_TT; i++){
		if(i < numTT){
			/*Thread *t = new Thread("TicketTaker thread");*/
			/*t->Fork(ticketTaker, i);*/
			Fork(ticketTaker);
		}
	}
	
	/* technician forking */
	/*Thread *temp = new Thread("Technician thread");*/
	/*temp->Fork(technician, 0);*/
	Fork(technician);
	
	/* manager forking */
	/*temp = new Thread("Manager Thread");*/
	/*temp->Fork(manager, 0);*/
	Fork(manager);
	
	
	/* customer forking */
	for(i = 0; i < maxCust; i++){
		if(customerIsHeadCustomer[i]){
			/*Thread *t = new Thread("HeadCustomer thread");*/
			/*t->Fork(headCustomer, customerGroupNumber[i]);*/
			Fork(headCustomer);

			for(j = 0; j < groupSize[customerGroupNumber[i]]; j++){
				/*t = new Thread("RegularCustomer thread");*/
				/*t->Fork(regularCustomer, i+j+1);*/
				Fork(regularCustomer);
			}
		}
	}
	/* END: Forking Threads */
	Exit(0);
}

void runTheater(){
/*Write("runTheater Called.\n", 19, ConsoleOutput);*/

theaterInitializations(2,2,2,60);

return;
}


int main(){
	/*Write("Main Called.\n", 13, ConsoleOutput);*/
	runTheater();
	return 0;
}